<?php
/*********************/
/*                   */
/* http://www.ymd.cc */
/*********************/
/*    QQ: 11121426   */
/*                   */

/*********************/

class mdl_serverinfo
{

    public $allow_change_db = false;
    public $maxLevel = 6;

    public function run()
    {
        $return = array();
        $totalScore = 0;
        $allow_install = true;
        foreach (get_class_methods($this) as $func) {
            if (substr($func, 0, 5) == "test_") {
                $score = 0;
                $result = $this->$func($score);
                if ($result['items']) {
                    $group[$result['group']]['type'] = $result['type'];
                    $group[$result['group']]['items'] = array_merge($group[$result['group']['items']] ? $group[$result['group']['items']] : array(), $result['items']);
                    if ($allow_install && isset($result['allow_install'])) {
                        $allow_install = $result['allow_install'];
                    }
                    if ($result['key']) {
                        $return[$result['key']] =& $group[$result['group']]['items'];
                    }
                }
                $totalScore += $score;
            }
        }
        $score = floor($totalScore / 100) + 1;
        $rank = min($score, $this->maxLevel + 1);
        $level = array("E", "D", "C", "B", "A", "S");
        $return['data'] = $group;
        $return['score'] = $totalScore;
        $return['level'] = $level[$rank - 1];
        $return['rank'] = $rank;
        $return['allow_install'] = $allow_install;
        return $return;
    }

    public function test_basic($score)
    {
        $items['操作系统'] = PHP_OS;
        $items['服务器软件'] = $_SERVER['SERVER_SOFTWARE'];
        $runMode = null;
        $runMode = php_sapi_name();
        switch ($runMode) {
            case "cgi-fcgi" :
                $score += 50;
                break;
        }
        $safemodeStr = "<span style=\"color:red\">(安全模式)</span>";
        if ($runMode) {
            if (ini_get("safe_mode")) {
                $runMode .= "&nbsp;";
            }
            $items['php运行方式'] = $runMode;
        } else if (ini_get("safe_mode")) {
            $items['php运行方式'] = $safemodeStr;
        }
        return array(
            "group" => "服务器基本信息",
            "key" => "basic",
            "items" => $items
        );
    }

    public function test_php(&$score)
    {
        $items['php版本'] = PHP_VERSION;
        if (is_callable("file_put_contents")) {
            $score += 40;
        }
        if (is_callable("str_ireplace")) {
            $score += 20;
        }
        if (is_callable("ftp_chmod")) {
            $score += 10;
        }
        if (is_callable("http_build_query")) {
            $score += 20;
        }
        $items['程序最多允许使用内存量&nbsp;memory_limit'] = ini_get("memory_limit");
        $items['POST最大字节数&nbsp;post_max_size'] = ini_get("post_max_size");
        $items['允许最大上传文件&nbsp;upload_max_filesize'] = ini_get("upload_max_filesize");
        $items['程序最长运行时间&nbsp;max_execution_time'] = ini_get("max_execution_time");
        $disableFunc = get_cfg_var("disable_functions");
        $items['被禁用的函数&nbsp;disable_functions'] = $disableFunc ? $disableFunc : "无";
        return array(
            "group" => "php基本信息",
            "items" => $items
        );
    }

    public function test_server_req(&$score)
    {
        $rst = version_compare(PHP_VERSION, "4.0", ">=");
        $items['PHP4以上'] = array(
            "value" => PHP_VERSION,
            "result" => $rst
        );
        if (!$rst) {
            $allow_install = false;
        }
        $rst = !get_cfg_var("zend.ze1_compatibility_mode");
        $items['zend.ze1_compatibility_mode 关闭'] = array(
            "value" => $rst ? "Off" : "On",
            "result" => $rst
        );
        if (!$rst) {
            $allow_install = false;
        }
        $tmpfname = tempnam("../home/cache", "foo");
        $handle = fopen($tmpfname, "w");
        $rst = flock($handle, LOCK_EX);
        fclose($handle);
        unlink($tmpfname);
        $items['支持文件锁(flock)'] = array(
            "value" => $rst ? "支持" : "不支持",
            "result" => $rst
        );
        if (!$rst) {
            $allow_install = false;
        }
        $rst = function_exists("xml_parse_into_struct");
        $items['php可以解析xml文件'] = array(
            "value" => $rst ? "支持" : "不支持",
            "result" => $rst
        );
        if (!$rst) {
            $allow_install = false;
        }
        $rst = function_exists("mysql_connect") && function_exists("mysql_get_server_info");
        $items['MySQL函数库可用'] = array(
            "value" => $rst ? mysql_get_client_info() : "未安装",
            "result" => $rst
        );
        if (!$rst) {
            $allow_install = false;
        } else {
            $rst = false;
            if (defined("DB_HOST")) {
                if (defined("DB_PASSWORD")) {
                    $rs = mysql_connect(DB_HOST, DB_USER, DB_PASSWORD);
                } else if (defined("DB_USER")) {
                    $rs = mysql_connect(DB_HOST, DB_USER);
                } else {
                    $rs = mysql_connect(DB_HOST);
                }
                $db_ver = mysql_get_server_info($rs);
            } else if ($db_ver = mysql_get_server_info()) {
                define("DB_HOST", "");
            } else {
                $sock = get_cfg_var("mysql.default_socket");
                if (PHP_OS != "WINNT" && file_exists($sock) && is_writable($sock)) {
                    define("DB_HOST", $sock);
                } else {
                    $host = ini_get("mysql.default_host");
                    $port = ini_get("mysql.default_port");
                    if (!$host) {
                        $host = "127.0.0.1";
                    }
                    if (!$port) {
                        $port = 3306;
                    }
                    define("DB_HOST", $host . ":" . $port);
                }
            }
            if (!$db_ver) {
                if (substr(DB_HOST, 0, 1) == "/") {
                    $fp = @fsockopen("unix://" . DB_HOST);
                } else {
                    if ($p = strrpos(DB_HOST, ":")) {
                        $port = substr(DB_HOST, $p + 1);
                        $host = substr(DB_HOST, 0, $p);
                    } else {
                        $port = 3306;
                        $host = DB_HOST;
                    }
                    $fp = @fsockopen("tcp://" . $host, $port, $errno, $errstr, 2);
                }
                if (!$fp) {
                    $db_ver = "无法连接";
                } else {
                    fwrite($fp, "\n");
                    $db_ver = fread($fp, 20);
                    fclose($fp);
                    if (preg_match("/([2-8]\\.[0-9\\.]+)/", $db_ver, $match)) {
                        $db_ver = $match[1];
                        $rst = version_compare($db_ver, "3.2.23", ">=");
                    } else {
                        $db_ver = "无法识别";
                    }
                }
            } else {
                $rst = version_compare($db_ver, "3.2.23", ">=");
            }
            $this->db_ver = $db_ver;
            $mysql_key = "数据库Mysql 3.2.23以上&nbsp;<i style=\"color:#060\">" . DB_HOST . "</i>";
            if ($this->allow_change_db) {
                $mysql_key .= "<form method=\"get\" action=\"\" style=\"margin:0;padding:0\"><table><tr><td><label for=\"db_host\">MySQL主机</label></td><td>&nbsp;</td></tr><tr><td><input id=\"db_host\" value=\"" . DB_HOST . "\" name=\"db_host\" style=\"width:100px;\" type=\"text\" /></td><td><input type=\"submit\" value=\"连接\"></td></tr></table></form>";
            }
            $items[$mysql_key] = array(
                "value" => $db_ver,
                "result" => $rst
            );
            if (!$rst) {
                $allow_install = false;
            }
            $rst = defined("OPTIMIZER_VERSION") || function_exists("extension_loaded") && extension_loaded("Zend Optimizer");
            if ($rst) {
                if (defined("OPTIMIZER_VERSION")) {
                    $rst = version_compare(OPTIMIZER_VERSION, "2.5.7", ">=");
                    $value = OPTIMIZER_VERSION;
                } else {
                    $value = "通过";
                }
            } else {
                $value = "未安装";
            }
            $items['ZEND Optimizer2.5.7以上'] = array(
                "value" => $value,
                "result" => $rst
            );
            if (!$rst) {
                $allow_install = false;
            }
        }
        if (ini_get("safe_mode")) {
            $rst = is_callable("ftp_connect");
            if (!$rst) {
                $allow_install = false;
            }
            $items['当安全模式开启时,ftp函数可用'] = array(
                "value" => $rst ? "可用" : "不可用",
                "result" => $rst
            );
        }
        $rst = preg_match("/[0-9]+\\.[0-9]+\\.[0-9]+\\.[0-9]+/", gethostbyname("www.example.com"));
        $items['DNS配置完成,本机上能通过域名访问网络'] = array(
            "value" => $rst ? "成功" : "失败 (将影响部分功能)",
            "result" => $rst
        );
        return array(
            "group" => "基本需求",
            "key" => "require",
            "items" => $items,
            "type" => "require",
            "allow_install" => $allow_install
        );
    }

    public function test_php_req(&$score)
    {
        $rst = PHP_OS != "WINNT";
        $items['unix/linux 主机'] = array(
            "value" => PHP_OS,
            "result" => $rst
        );
        if ($rst) {
            $score += 30;
        } else {
            $this->maxLevel(5);
        }
        $rst = version_compare(PHP_VERSION, "5.2", ">=");
        $items['php 版本5.2.0以上'] = array(
            "value" => PHP_VERSION,
            "result" => $rst
        );
        if ($rst) {
            $score += 20;
        } else {
            $this->maxLevel(5);
        }
        $rst = version_compare($this->db_ver, "4.1.2", ">=");
        $items['MySQL版本 4.1.2 以上'] = array(
            "value" => $this->db_ver,
            "result" => $rst
        );
        if ($rst) {
            $score += 100;
        } else {
            $this->maxLevel(5);
        }
        $gdscore = 0;
        $gd_rst = array();
        if ($rst = is_callable("gd_info")) {
            $gdinfo = gd_info();
            if ($gdinfo['FreeType Support']) {
                $gd_rst[] = "freetype";
                $gdscore += 15;
            }
            if ($gdinfo['GIF Read Support']) {
                $gd_rst[] = "gif";
                $gdscore += 10;
            }
            if ($gdinfo['JPG Support']) {
                $gd_rst[] = "jpg";
                $gdscore += 10;
            }
            if ($gdinfo['PNG Support']) {
                $gd_rst[] = "png";
                $gdscore += 10;
            }
            if ($gdinfo['WBMP Support']) {
                $gd_rst[] = "bmp";
                $gdscore += 5;
            }
        }
        $items['GD支持'] = array(
            "value" => $rst ? implode(",", $gd_rst) : "不支持",
            "result" => $rst
        );
        if ($rst) {
            $score += $gdscore;
        } else {
            $this->maxLevel(2);
        }
        if (isset($GLOBALS['system'])) {

            $system =& $GLOBALS['system'];
            $url = parse_url($system->base_url());
            $code = substr(md5(time()), 0, 6);
            $content = $this->doHttpQuery($url['path'] . "/_test_rewrite=1&s=" . $code . "&a.html");
            $rst = strpos($content, "[*[" . md5($code) . "]*]");
            $items['支持rewrite'] = array(
                "value" => $rst ? "支持" : "不支持",
                "result" => $rst,
                "key" => "rewrite"
            );
            $content = $this->doHttpQuery($url['path'] . "/statics/head.jgz");
            $rst = preg_match("/Content\\-Type:\\s*text\\/javascript/i", $content);
            $items['支持将jgz输出为text/javascript'] = array(
                "value" => $rst ? "支持" : "不支持",
                "result" => $rst,
                "key" => "mimejgz"
            );
        }
        $rst = is_callable("gzcompress");
        $items['Zlib支持'] = array(
            "value" => $rst ? "支持" : "不支持",
            "result" => $rst
        );
        if ($rst) {
            $score += 80;
        } else {
            $this->maxLevel(2);
        }
        $rst = is_callable("json_decode");
        $items['Json支持'] = array(
            "value" => $rst ? "支持" : "不支持",
            "result" => $rst
        );
        if ($rst) {
            $score += 30;
        } else {
            $this->maxLevel(5);
        }
        $rst = is_callable("mb_internal_encoding");
        $items['mbstring支持'] = array(
            "value" => $rst ? "支持" : "不支持",
            "result" => $rst
        );
        if ($rst) {
            $score += 25;
        } else {
            $this->maxLevel(5);
        }
        $rst = is_callable("fsockopen");
        $items['fsockopen支持'] = array(
            "value" => $rst ? "支持" : "不支持",
            "result" => $rst
        );
        if ($rst) {
            $score += 50;
        } else {
            $this->maxLevel(5);
        }
        $rst = is_callable("iconv");
        $items['iconv支持'] = array(
            "value" => $rst ? "支持" : "不支持",
            "result" => $rst
        );
        if ($rst) {
            $score += 25;
        } else {
            $this->maxLevel(5);
        }
        $rst = ini_get("register_globals");
        $items['register_globals关闭'] = array(
            "value" => $rst ? "开启" : "已关闭",
            "result" => !$rst
        );
        if (!$rst) {
            $score += 15;
        } else {
            $this->maxLevel(2);
        }
        if (version_compare(PHP_VERSION, "5.2.0", ">=")) {
            $rst = ini_get("allow_url_include关闭");
            $items['allow_url_include关闭 (php5.2.0以上)'] = array(
                "value" => $rst ? "开启" : "已关闭",
                "result" => !$rst
            );
            if ($rst) {
                $score += 30;
            } else {
                $this->maxLevel(5);
            }
        } else {
            $rst = ini_get("allow_url_fopen");
            $items['allow_url_fopen关闭 (版本小于php5.2.0)'] = array(
                "value" => $rst ? "开启" : "已关闭",
                "result" => !$rst
            );
            if ($rst) {
                $score += 30;
            } else {
                $this->maxLevel(5);
            }
        }
        $rst = null;
        if ($cache_apc = is_callable("apc_store")) {
            $rst[] = "APC";
        }
        if ($cache_memcached = class_exists("Memcache")) {
            $rst[] = "Memcached";
        }
        $items['高速缓存模块(apc,memcached)'] = array(
            "value" => $rst ? implode(",", $rst) : "无",
            "result" => $cache_apc || $cache_memcached
        );
        if ($cache_apc || $cache_memcached) {
            $score += 150;
        } else {
            $this->maxLevel(4);
        }
        return array(
            "group" => "推荐配置",
            "items" => $items,
            "type" => "require"
        );
    }

    public function maxLevel($level)
    {
        $this->maxLevel = min($this->maxLevel, $level - 1);
    }

    public function doHttpQuery($uri)
    {
        $fp = fsockopen(isset($_SERVER['SERVER_ADDR']) ? $_SERVER['SERVER_ADDR'] : $_SERVER['HTTP_HOST'], $_SERVER['SERVER_PORT'], $errno, $errstr, 2);
        if ($fp) {
            $out = "GET " . preg_replace("#/+#", "/", $uri) . " HTTP/1.1\r\n";
            $out .= "Host: {$_SERVER['HTTP_HOST']}\r\n";
            $out .= "Connection: Close\r\n\r\n";
            fwrite($fp, $out);
            while (!feof($fp) && strlen($content) < 512) {
                $content .= fgets($fp, 128);
            }
            fclose($fp);
            return $content;
        } else {
            return false;
        }
    }

}

?>
